import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'el-input-number',
  templateUrl: './el-input-number.component.html',
  styleUrls: ['./el-input-number.component.css','./input-number.css']
})
export class ElInputNumberComponent implements OnInit {
  
  // prop
  @Input() controls:boolean=true;
  @Input() value:number=0;
  @Input() min:number;
  @Input() max:number;
  @Input() step:number=1;
  @Input() size:string;
  @Input() disabled:boolean=false;
  @Input() debounce:number=300;
  
  @Output() valueChange:EventEmitter<number>=new EventEmitter<number>()
  // state
  minDisabled:boolean;
  maxDisabled:boolean;
  currentValue:number=0;
  inputTimer:any=null;
  sizeClass:string
  // method
  
  getMaxAndMinDisabled(){
    if(!this.min&&this.min!==0){this.minDisabled=false}else{
        this.minDisabled=Number(this.value)-Number(this.step)<Number(this.min);
    }
     
    if(!this.max&&this.max!==0){this.maxDisabled=false;}else{
        this.maxDisabled=Number(this.value)+Number(this.step)>Number(this.max)
    }
    
     
  }

  handleKeydown(e){
      // console.log(e.keyCode)
      if(e.keyCode===38){
          this.increase()
      }else if(e.keyCode===40){
          this.decrease()
      }else{
        return
      }

  }
  handleInput(e){
      if(this.inputTimer){
          clearTimeout(this.inputTimer)
      }
      this.inputTimer=setTimeout(()=>{
          let tempValue=e.target.value;
          if(tempValue===''){return};
          tempValue=Number(tempValue);
          if(!isNaN(tempValue)){
              this.setCurrentValue(tempValue)
          }else{
              e.target.value=this.currentValue
          }
          
      },this.debounce)
  }

  decrease(){
      this.getMaxAndMinDisabled()
      if(this.disabled||this.minDisabled){return};
      const value=this.value;
      const newVal = this._decrease(value, this.step);
      if (newVal < this.min) {return};
      this.setCurrentValue(newVal);
  }
  increase(){
      this.getMaxAndMinDisabled()
      if(this.disabled||this.maxDisabled){return};
      const value =this.value;
      const newVal = this._increase(value, this.step);
      if (newVal > this.max) {return};
      this.setCurrentValue(newVal);
  }
  

  constructor() { }

  ngOnInit() {
      this.sizeClass=this.size?`el-input-number--${this.size}`:''
  }


  // other function
  _decrease(val,step){
      val=Number(val),step=Number(step);
      if(typeof val!=='number'){return this.currentValue;}
      const precisionFactor=Math.pow(10,this.precision());
      return this.toPrecision((precisionFactor*val-precisionFactor*step)/precisionFactor)
  }
  _increase(val, step) {
    val=Number(val),step=Number(step);
    if (typeof val !== 'number') {return this.currentValue};

    const precisionFactor = Math.pow(10, this.precision());

    return this.toPrecision((precisionFactor * val + precisionFactor * step) / precisionFactor);
  }

  // computed
  precision():number{
      const {value,step,getPrecision} =this;
      return Math.max(getPrecision(value),getPrecision(step))
  }
  getPrecision(value){
      const valueStr=value.toString();
      const dotPosition=valueStr.indexOf('.');
      let precision=0;
      if(dotPosition!==-1){
          precision=valueStr.length-dotPosition-1;
      }
      return precision;
  }
  toPrecision(num,precision?){
      if(precision===undefined){precision=this.precision}
      return parseFloat(parseFloat(Number(num).toFixed(precision)).toString())
  }
  setCurrentValue(newVal){
      const oldVal=this.currentValue;
      if(this.max!==undefined&& newVal>=this.max){newVal=this.max}
      if(this.min!==undefined&&newVal<=this.min){newVal=this.min}
      this.currentValue=newVal;
      this.value=newVal;
      this.valueChange.emit(newVal)
      this.getMaxAndMinDisabled()
  }
  
}
